Node.js Performance Diagnostics

Node.js பயன்பாடுகளின் செயல்திறன் சிக்கல்களைக் கண்டறியும் கருவிகள் மற்றும் நுட்பங்களைக் கற்றுக்கொள்ளுங்கள்

செயல்திறன் ஏன் முக்கியமானது

Node.js செயல்திறன் சிக்கல்களைக் கண்டறிவதற்கு பல்வேறு கருவிகள் மற்றும் நுட்பங்களை வழங்குகிறது.

இந்த வழிகாட்டி உள்ளமைக்கப்பட்ட கருவிகள் மற்றும் பிரபலமான மூன்றாம் தரப்பு தீர்வுகளை உள்ளடக்கியது, விரிவான செயல்திறன் பகுப்பாய்வுக்காக.

💡 செயல்திறன் உதவிக்குறிப்பு:

எப்போதும் மேம்படுத்துவதற்கு முன் அளவிடவும்.

செயல்திறன் சிக்கல்கள் எங்கே இருக்கக்கூடும் என்று யூகிப்பதற்குப் பதிலாக உண்மையான தடைகளை அடையாளம் காண இந்த வழிகாட்டியில் உள்ள நுட்பங்களைப் பயன்படுத்தவும்.

Node.js செயல்திறனைப் புரிந்துகொள்வது

Node.js பயன்பாடுகளில் செயல்திறன் பல காரணிகளால் பாதிக்கப்படலாம்:

இவெண்ட் லூப்பைத் தடுக்கும் CPU-தீவிர செயல்பாடுகள்
நினைவக கசிவுகள் மற்றும் அதிகப்படியான குப்பை சேகரிப்பு
I/O தடைகள் (தரவுத்தள வினவல்கள், கோப்பு செயல்பாடுகள், நெட்வொர்க் கோரிக்கைகள்)
திறனற்ற குறியீடு மற்றும் அல்காரிதம்கள்
இவெண்ட் லூப் நெரிசல்

இந்த சிக்கல்களைக் கண்டறிய முறையான அணுகுமுறை மற்றும் சரியான கருவிகள் தேவை.

உள்ளமைக்கப்பட்ட கண்டறியும் கருவிகள்

console.time() மற்றும் console.timeEnd()

ஒரு செயல்பாடு எவ்வளவு நேரம் எடுக்கும் என்பதை அளவிட எளிய வழி:

// Measure execution time
console.time('operation');

// Some operation to measure
const array = Array(1000000).fill().map((_, i) => i);
array.sort((a, b) => b - a);

console.timeEnd('operation');
// Output: operation: 123.45ms

செயல்முறை புள்ளிவிவரங்கள்

Node.js செயல்முறை உலகளாவிய பொருளின் மூலம் செயல்முறை புள்ளிவிவரங்களுக்கான அணுகலை வழங்குகிறது:

// Memory usage
const memoryUsage = process.memoryUsage();
console.log('Memory Usage:');
console.log(` RSS: ${Math.round(memoryUsage.rss / 1024 / 1024)} MB`);
console.log(` Heap Total: ${Math.round(memoryUsage.heapTotal / 1024 / 1024)} MB`);
console.log(` Heap Used: ${Math.round(memoryUsage.heapUsed / 1024 / 1024)} MB`);
console.log(` External: ${Math.round(memoryUsage.external / 1024 / 1024)} MB`);

// CPU usage
const startUsage = process.cpuUsage();

// Simulate CPU work
const now = Date.now();
while (Date.now() - now < 500); // Busy wait for 500ms

const endUsage = process.cpuUsage(startUsage);
console.log('CPU Usage:');
console.log(` User: ${endUsage.user / 1000}ms`);
console.log(` System: ${endUsage.system / 1000}ms`);

// Uptime
console.log(`Process uptime: ${process.uptime().toFixed(2)} seconds`);

Node.js Performance Hooks

Node.js 8.5.0 முதல், perf_hooks தொகுதி செயல்திறனை அளவிடுவதற்கான கருவிகளை வழங்குகிறது:

const { performance, PerformanceObserver } = require('perf_hooks');

// Create a performance observer
const obs = new PerformanceObserver((items) => {
  items.getEntries().forEach((entry) => {
    console.log(`${entry.name}: ${entry.duration.toFixed(2)}ms`);
  });
});

// Subscribe to performance events
obs.observe({ entryTypes: ['measure'] });

// Mark the beginning of an operation
performance.mark('start');

// Simulate some work
const data = [];
for (let i = 0; i < 1000000; i++) {
  data.push(i * i);
}

// Mark the end and measure
performance.mark('end');
performance.measure('Data processing time', 'start', 'end');

// Clean up marks
performance.clearMarks();

மேம்பட்ட CPU சுயவிவரம்

CPU சுயவிவரத்தை எப்போது பயன்படுத்துவது

அதிக CPU நேரத்தை உட்கொள்ளும் சூடான செயல்பாடுகளை அடையாளம் காணுதல்
ஒத்திசைவான குறியீட்டில் மேம்பாட்டு வாய்ப்புகளைக் கண்டறிதல்
இவெண்ட் லூப் தடுப்பு செயல்பாடுகளை பகுப்பாய்வு செய்தல்
மேம்பாடுகளுக்கு முன்னும் பின்னும் செயல்திறனை ஒப்பிடுதல்

1. Source Maps உடன் V8 Profiler

TypeScript அல்லது transpiled JavaScript ஐப் பயன்படுத்தும் பயன்பாடுகளுக்கு, அர்த்தமுள்ள சுயவிவர முடிவுகளுக்கு source maps அவசியம்:

const v8Profiler = require('v8-profiler-node8');
const fs = require('fs');
const path = require('path');

// Enable source map support for accurate profiling
require('source-map-support').install();

// Start CPU profiling with source map support
v8Profiler.setGenerateType(1); // Include type information
const profile = v8Profiler.startProfiling('CPU profile', true);

// Run code to profile
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}

// Simulate both CPU and I/O work
function processData() {
  const start = Date.now();
  fibonacci(35);
  console.log(`CPU work took: ${Date.now() - start}ms`);

  // Simulate async work
  setImmediate(() => {
    const asyncStart = Date.now();
    fibonacci(30);
    console.log(`Async work took: ${Date.now() - asyncStart}ms`);
  });
}

processData();

// Stop profiling after async work completes
setTimeout(() => {
  const profile = v8Profiler.stopProfiling('CPU profile');
  profile.export((error, result) => {
    const filename = path.join(__dirname, 'profile.cpuprofile');
    fs.writeFileSync(filename, result);
    console.log(`CPU profile saved to ${filename}`);
    profile.delete();
  });
}, 1000);

📦 நிறுவல்:

மேலே உள்ள எடுத்துக்காட்டைப் பயன்படுத்த, நீங்கள் v8-profiler தொகுப்பை நிறுவ வேண்டும்:

npm install v8-profiler-node8

உருவாக்கப்பட்ட .cpuprofile கோப்பை Chrome DevTools இல் காட்சிப்படுத்துவதற்கு ஏற்ற முடியும்.

2. Node.js உள்ளமைக்கப்பட்ட சுயவிவரம்

Node.js கட்டளை வரி கொடிகளின் மூலம் அணுகக்கூடிய உள்ளமைக்கப்பட்ட சுயவிவர திறன்களைக் கொண்டுள்ளது:

# Start a Node.js application with profiling enabled
node --prof app.js

# Process the generated log file
node --prof-process isolate-0xNNNNNNNN-NNNN-v8.log > processed.txt

மேம்பட்ட நினைவக சுயவிவரம்

🔍 நினைவக கசிவு கண்டறிதல் உதவிக்குறிப்பு:

வெவ்வேறு நேரங்களில் எடுக்கப்பட்ட பல heap snapshots ஐ ஒப்பிட்டு, எதிர்பார்த்தபடி குப்பை சேகரிக்கப்படாத பொருள்களை அடையாளம் காணவும்.

Chrome DevTools உடன் Heap Snapshots

Heap snapshots ஒரு குறிப்பிட்ட தருணத்தில் நினைவக நிலையைப் பிடிப்பதன் மூலம் நினைவக கசிவுகளை அடையாளம் காண உதவுகின்றன:

const heapdump = require('heapdump');
const fs = require('fs');
const path = require('path');

// Generate some data that might leak
let leakyData = [];
function potentiallyLeaky() {
  const data = {
    id: Date.now(),
    content: Array(1000).fill('potentially leaky data'),
    timestamp: new Date().toISOString()
  };
  leakyData.push(data);
} 
// Simulate a memory leak with different retention patterns
setInterval(() => {
  potentiallyLeaky();
  // Keep only the last 100 items to simulate a partial leak
  if (leakyData.length > 100) {
    leakyData = leakyData.slice(-100);
  }
}, 100);
// Take heap snapshots at intervals
function takeHeapSnapshot(prefix) {
  const filename = path.join(__dirname, `${prefix}-${Date.now()}.heapsnapshot`);
  heapdump.writeSnapshot(filename, (err, filename) => {
    if (err) {
      console.error('Failed to take heap snapshot:', err);
    } else {
      console.log(`Heap snapshot saved to ${filename}`);
    }
  });
}
// Initial snapshot takeHeapSnapshot('heap-initial');
// Take periodic snapshots
setInterval(() => {   takeHeapSnapshot('heap-periodic');
}, 10000);
// Force garbage collection before final snapshot
setTimeout(() => {
  if (global.gc) {
    global.gc();
    console.log('Garbage collection forced');
  }
  takeHeapSnapshot('heap-final');
}, 30000);

📦 நிறுவல்:

மேலே உள்ள எடுத்துக்காட்டைப் பயன்படுத்த, நீங்கள் heapdump தொகுப்பை நிறுவ வேண்டும்:

npm install heapdump

Heap snapshots நினைவக கசிவுகளை அடையாளம் காண Chrome DevTools இல் பகுப்பாய்வு செய்யப்படலாம்.

இவெண்ட் லூப் மற்றும் பின்னடைவு பகுப்பாய்வு

கண்காணிக்க வேண்டிய இவெண்ட் லூப் அளவீடுகள்

இவெண்ட் லூப் பின்தங்கல் (இவெண்ட் லூப் டிக்குகளுக்கு இடையே உள்ள நேரம்)
செயலில் உள்ள கைப்பிடிகள் மற்றும் கோரிக்கைகள்
நிலுவையில் உள்ள அசிங்க்ரோன் செயல்பாடுகள்
குப்பை சேகரிப்பு இடைநிறுத்தங்கள்

இவெண்ட் லூப் Node.js செயல்திறனுக்கு மையமானது. அதைத் தடுப்பது செயல்திறன் சீரழிவை ஏற்படுத்துகிறது:

const toobusy = require('toobusy-js');
const http = require('http');

// Configure thresholds (in milliseconds)
toobusy.maxLag(100); // Maximum allowed lag before considering server too busy
toobusy.interval(500); // Check interval for event loop lag

// Create HTTP server with event loop monitoring
const server = http.createServer((req, res) => {
  // Check if event loop is overloaded
  if (toobusy()) {
    res.statusCode = 503; // Service Unavailable
    res.setHeader('Retry-After', '10');
    return res.end(JSON.stringify({
      error: 'Server is too busy',
      message: 'Please try again later',
      status: 503
    }));
  }
  // Simulate some work based on URL
  if (req.url === '/compute') {
    // CPU-intensive work
    let sum = 0;
    for (let i = 0; i < 1e7; i++) {
      sum += Math.random();
    }
    res.end(`Computed: ${sum}`);
  } else {
    // Normal response
    res.end('OK');
  }
});
// Add error handling
server.on('error', (err) => {
  console.error('Server error:', err);
});
// Start server
const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});
// Monitor event loop lag and memory usage
setInterval(() => {
  const lag = toobusy.lag();
  const mem = process.memoryUsage();
  console.log(`Event loop lag: ${lag}ms`);
  console.log(`Memory usage: ${Math.round(mem.heapUsed / 1024 / 1024)}MB / ${Math.round(mem.heapTotal / 1024 / 1024)}MB`);
}, 1000);
// Graceful shutdown
process.on('SIGINT', () => {
  console.log('Shutting down...');
  server.close(() => {
    process.exit(0);
  });
});

📦 நிறுவல்:

மேலே உள்ள எடுத்துக்காட்டைப் பயன்படுத்த, நீங்கள் toobusy-js தொகுப்பை நிறுவ வேண்டும்:

npm install toobusy-js

Flame Graphs

Flame graphs CPU மாதிரி எடுப்பின் காட்சிப் பிரதிநிதித்துவத்தை வழங்குகின்றன, உங்கள் பயன்பாட்டில் நேரம் எங்கு செலவிடப்படுகிறது என்பதை அடையாளம் காண உதவுகின்றன:

# Using 0x for flame graphs (install globally)
npm install -g 0x

# Run your application with 0x
0x app.js

# A browser will open with the flame graph visualization when the process exits

Benchmarking

Benchmarking மிகவும் திறமையான ஒன்றைத் தேர்ந்தெடுக்க வெவ்வேறு செயலாக்கங்களை ஒப்பிட உதவுகிறது:

const Benchmark = require('benchmark');
const suite = new Benchmark.Suite;

// Add tests
suite
  .add('RegExp#test', function() {
    /o/.test('Hello World!');
  })
  .add('String#indexOf', function() {
    'Hello World!'.indexOf('o') > -1;
  })
  .add('String#includes', function() {
    'Hello World!'.includes('o');
  })
  // Add listeners
  .on('cycle', function(event) {
    console.log(String(event.target));
  })
  .on('complete', function() {
    console.log('Fastest is ' + this.filter('fastest').map('name'));
  })
  // Run benchmarks
  .run({ 'async': true });

📦 நிறுவல்:

மேலே உள்ள எடுத்துக்காட்டைப் பயன்படுத்த, நீங்கள் benchmark தொகுப்பை நிறுவ வேண்டும்:

npm install benchmark

Node.js Inspector

Node.js Chrome DevTools மூலம் அணுகக்கூடிய ஒரு ஒருங்கிணைந்த debugger மற்றும் profiler ஐக் கொண்டுள்ளது:

# Start an application with the inspector
node --inspect app.js

# Start and immediately break (for debugging)
node --inspect-brk app.js

Chrome ஐத் திறந்து chrome://inspect க்குச் சென்று உங்கள் Node.js பயன்பாட்டிற்கான DevTools ஐ அணுகவும். இது அணுகலை வழங்குகிறது:

CPU profiler
Memory heap snapshots
Memory allocation timeline
Debugger

Clinic.js Suite

Clinic.js என்பது Node.js பயன்பாடுகளில் செயல்திறன் சிக்கல்களைக் கண்டறிவதற்கான கருவிகளின் தொகுப்பாகும்:

# Install the Clinic.js suite
npm install -g clinic

# Use Doctor to identify issues
clinic doctor -- node app.js

# Use Flame to generate CPU flame graphs
clinic flame -- node app.js

# Use Bubbleprof for async operations analysis
clinic bubbleprof -- node app.js

நடைமுறை செயல்திறன் கண்டறிதல்

படி 1: அடிப்படை அளவீடுகளை நிறுவவும்

மேம்படுத்துவதற்கு முன், உங்கள் பயன்பாட்டிற்கான அடிப்படை அளவீடுகளை நிறுவவும்:

const autocannon = require('autocannon');
const { writeFileSync } = require('fs');

// Run a benchmark against your application
const result = autocannon({
  url: 'http://localhost:8080',
  connections: 100,
  duration: 10
});

// Save the results
result.on('done', (results) => {
  console.log('Baseline performance metrics:');
  console.log(` Requests/sec: ${results.requests.average}`);
  console.log(` Latency: ${results.latency.average}ms`);

  writeFileSync('baseline-metrics.json', JSON.stringify(results, null, 2));
});

படி 2: தடைகளை அடையாளம் காணவும்

தடைகளை அடையாளம் காண சுயவிவரத்தைப் பயன்படுத்தவும்:

கணினி-தீவிர செயல்பாடுகளுக்கான CPU சுயவிவரம்
நினைவக கசிவுகளுக்கான நினைவக snapshots
அழைப்பு ஸ்டாக் பகுப்பாய்வுக்கான Flame graphs
I/O மற்றும் callback தாமதங்களுக்கான இவெண்ட் லூப் கண்காணிப்பு

படி 3: சரிசெய்து சரிபார்க்கவும்

மேம்பாடுகளைப் பயன்படுத்திய பிறகு, உங்கள் அடிப்படைக்கு எதிரான மேம்பாடுகளைச் சரிபார்க்கவும்.

பொதுவான செயல்திறன் சிக்கல்கள் மற்றும் தீர்வுகள்

1. நினைவக கசிவுகள்

அறிகுறிகள்: காலப்போக்கில் அதிகரித்து வரும் நினைவக பயன்பாடு, இது தட்டையாக இல்லை.

தீர்வுகள்:

இடைவெளியில் heap snapshots எடுத்து ஒப்பிடவும்
குறிப்புகளைத் தக்கவைக்கும் உலகளாவிய மாறிகள், event listeners மற்றும் closures ஐச் சரிபார்க்கவும்
பொருள்கள் இனி தேவையில்லாதபோது சரியான சுத்தம் செயல்படுத்தவும்

2. நீண்ட-இயங்கும் செயல்பாடுகள்

அறிகுறிகள்: அதிக இவெண்ட் லூப் பின்தங்கல், சீரற்ற பதில் நேரங்கள்.

தீர்வுகள்:

CPU-தீவிர வேலையை worker threads க்கு நகர்த்தவும்
setImmediate/process.nextTick ஐப் பயன்படுத்தி நீண்ட பணிகளை சிறிய துண்டுகளாக உடைக்கவும்
அர்ப்பணிக்கப்பட்ட சேவைகளுக்கு இடமாற்றம் செய்வதைக் கவனியுங்கள்

3. திறனற்ற தரவுத்தள வினவல்கள்

அறிகுறிகள்: மெதுவான பதில் நேரங்கள், அதிக பின்னடைவு.

தீர்வுகள்:

தரவுத்தள செயல்பாடுகளை சுயவிவரம் செய்யவும்
சரியான அட்டவணைப்படுத்தலுடன் வினவல்களை மேம்படுத்தவும்
இணைப்பு குளம் பயன்படுத்தவும்
அடிக்கடி அணுகப்படும் தரவுக்கு caching செயல்படுத்தவும்

பயிற்சி

சரியான தொகுதி பெயரை தேர்வு செய்யவும்.

The ______ module in Node.js provides tools for measuring performance.

process
✗ தவறு! "process" தொகுதி செயல்முறை-தொடர்பான தகவல்களை வழங்குகிறது, ஆனால் செயல்திறன் அளவீட்டு கருவிகளை வழங்காது
console
✗ தவறு! "console" தொகுதி அடிப்படை பதிவு செயல்பாடுகளை வழங்குகிறது, ஆனால் மேம்பட்ட செயல்திறன் அளவீட்டு கருவிகளை வழங்காது
perf_hooks
✓ சரி! "perf_hooks" தொகுதி Node.js 8.5.0 முதல் செயல்திறனை அளவிடுவதற்கான கருவிகளை வழங்குகிறது
timers
✗ தவறு! "timers" தொகுதி அசிங்க்ரோன் செயல்பாடுகளை நேரமிடுவதற்கான செயல்பாடுகளை வழங்குகிறது, ஆனால் செயல்திறன் அளவீட்டு கருவிகளை வழங்காது